package com.sheng.leetcode.year2022.month08.day15;

import org.junit.Test;

import java.util.LinkedList;

/**
 * @author liusheng
 * @date 2022/08/15
 *
 * 641. 设计循环双端队列
 *
 * 设计实现双端队列。
 *
 * 实现 MyCircularDeque 类:
 * MyCircularDeque(int k) ：构造函数,双端队列最大为 k 。
 * boolean insertFront()：将一个元素添加到双端队列头部。 如果操作成功返回 true ，否则返回 false 。
 * boolean insertLast() ：将一个元素添加到双端队列尾部。如果操作成功返回 true ，否则返回 false 。
 * boolean deleteFront() ：从双端队列头部删除一个元素。 如果操作成功返回 true ，否则返回 false 。
 * boolean deleteLast() ：从双端队列尾部删除一个元素。如果操作成功返回 true ，否则返回 false 。
 * int getFront() )：从双端队列头部获得一个元素。如果双端队列为空，返回 -1 。
 * int getRear() ：获得双端队列的最后一个元素。 如果双端队列为空，返回 -1 。
 * boolean isEmpty() ：若双端队列为空，则返回 true ，否则返回 false  。
 * boolean isFull() ：若双端队列满了，则返回 true ，否则返回 false 。
 *
 * 示例 1：
 * 输入
 * ["MyCircularDeque", "insertLast", "insertLast", "insertFront", "insertFront", "getRear", "isFull", "deleteLast", "insertFront", "getFront"]
 * [[3], [1], [2], [3], [4], [], [], [], [4], []]
 * 输出
 * [null, true, true, true, false, 2, true, true, true, 4]
 *
 * 解释
 * MyCircularDeque circularDeque = new MycircularDeque(3); // 设置容量大小为3
 * circularDeque.insertLast(1);			        // 返回 true
 * circularDeque.insertLast(2);			        // 返回 true
 * circularDeque.insertFront(3);			        // 返回 true
 * circularDeque.insertFront(4);			        // 已经满了，返回 false
 * circularDeque.getRear();  				// 返回 2
 * circularDeque.isFull();				        // 返回 true
 * circularDeque.deleteLast();			        // 返回 true
 * circularDeque.insertFront(4);			        // 返回 true
 * circularDeque.getFront();				// 返回 4
 *
 * 提示：
 *
 * 1 <= k <= 1000
 * 0 <= value <= 1000
 * insertFront, insertLast, deleteFront, deleteLast, getFront, getRear, isEmpty, isFull  调用次数不大于 2000 次
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/design-circular-deque
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */
public class LeetCode0641 {

    @Test
    public void test01() {
        MyCircularDeque circularDeque = new MyCircularDeque(3);
        // 返回 true
        System.out.println(circularDeque.insertLast(1));
        // 返回 true
        System.out.println(circularDeque.insertLast(2));
        // 返回 true
        System.out.println(circularDeque.insertFront(3));
        // 已经满了，返回 false
        System.out.println(circularDeque.insertFront(4));
        // 返回 2
        System.out.println(circularDeque.getRear());
        // 返回 true
        System.out.println(circularDeque.isFull());
        // 返回 true
        System.out.println(circularDeque.deleteLast());
        // 返回 true
        System.out.println(circularDeque.insertFront(4));
        // 返回 4
        System.out.println(circularDeque.getFront());
    }
}
class MyCircularDeque {

    LinkedList<Integer> list;

    int length;

    /**
     * 构造函数,双端队列最大为 k
     *
     * @param k 队列长度
     */
    public MyCircularDeque(int k) {
        length = k;
        list = new LinkedList<>();
    }

    /**
     * 将一个元素添加到双端队列头部。 如果操作成功返回 true ，否则返回 false 。
     *
     * @param value 要添加进双端队列头部的元素
     * @return 操作是否成功
     */
    public boolean insertFront(int value) {
        if (isFull()) {
            return false;
        }
        list.addFirst(value);
        return true;
    }

    /**
     * 将一个元素添加到双端队列尾部。如果操作成功返回 true ，否则返回 false 。
     *
     * @param value 要添加进双端队列尾部的元素
     * @return 操作是否成功
     */
    public boolean insertLast(int value) {
        if (isFull()) {
            return false;
        }
        list.addLast(value);
        return true;
    }

    /**
     * 从双端队列头部删除一个元素。 如果操作成功返回 true ，否则返回 false 。
     *
     * @return 操作是否成功
     */
    public boolean deleteFront() {
        if (isEmpty()) {
            return false;
        }
        list.removeFirst();
        return true;
    }

    /**
     * 从双端队列尾部删除一个元素。如果操作成功返回 true ，否则返回 false 。
     *
     * @return 操作是否成功
     */
    public boolean deleteLast() {
        if (isEmpty()) {
            return false;
        }
        list.removeLast();
        return true;
    }

    /**
     * 从双端队列头部获得一个元素。如果双端队列为空，返回 -1 。
     *
     * @return 返回头部元素
     */
    public int getFront() {
        if (isEmpty()) {
            return -1;
        }
        return list.getFirst();
    }

    /**
     * 获得双端队列的最后一个元素。 如果双端队列为空，返回 -1 。
     *
     * @return 返回尾部元素
     */
    public int getRear() {
        if (isEmpty()) {
            return -1;
        }
        return list.getLast();
    }

    /**
     * 若双端队列为空，则返回 true ，否则返回 false  。
     *
     * @return 判断双端队列是否为空
     */
    public boolean isEmpty() {
        return list.isEmpty();
    }

    /**
     * 若双端队列满了，则返回 true ，否则返回 false 。
     *
     * @return 判断双端队列是否已满
     */
    public boolean isFull() {
        if (list.size() == length) {
            return true;
        } else {
            return false;
        }
    }
}

/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * MyCircularDeque obj = new MyCircularDeque(k);
 * boolean param_1 = obj.insertFront(value);
 * boolean param_2 = obj.insertLast(value);
 * boolean param_3 = obj.deleteFront();
 * boolean param_4 = obj.deleteLast();
 * int param_5 = obj.getFront();
 * int param_6 = obj.getRear();
 * boolean param_7 = obj.isEmpty();
 * boolean param_8 = obj.isFull();
 */
